package com.hopes.bizz.hazard.alarm.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hopes.bizz.basic.common.api.feign.RemoteParkBasicDictService;
import com.hopes.bizz.basic.hazard.source.entity.HazHazardSourceEntity;
import com.hopes.bizz.basic.hazard.source.entity.HazMonitorFactorEntity;
import com.hopes.bizz.common.core.util.CollectionUtils;
import com.hopes.bizz.common.core.util.DateUtils;
import com.hopes.bizz.hazard.alarm.dto.AlarmAnalysisRequest;
import com.hopes.bizz.hazard.alarm.dto.AlarmStatisticsRequest;
import com.hopes.bizz.hazard.alarm.entity.HazAlarmBrokenEntity;
import com.hopes.bizz.hazard.alarm.entity.HazAlarmOverproofEntity;
import com.hopes.bizz.hazard.alarm.service.HazAlarmBrokenService;
import com.hopes.bizz.hazard.alarm.service.HazAlarmOverproofService;
import com.hopes.bizz.hazard.alarm.service.HazAlarmStatisticsService;
import com.hopes.bizz.hazard.alarm.vo.HazAlarmStatistics;
import com.hopes.bizz.hazard.om.dto.HazRtDataHisDTO;
import com.hopes.bizz.hazard.om.entity.HazRtDataHisEntity;
import com.hopes.bizz.hazard.om.service.HazRtDataHisService;
import com.hopes.boss.common.core.constant.SecurityConstants;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/11/20 19:14
 * @Description:
 */
@Service
@RequiredArgsConstructor
public class HazAlarmStatisticsServiceImpl implements HazAlarmStatisticsService {

    private final HazAlarmOverproofService hazAlarmOverproofService;
    private final HazAlarmBrokenService hazAlarmBrokenService;
    private final RemoteParkBasicDictService remoteParkBasicDictService;
    private final HazRtDataHisService hazRtDataHisService;

    private DecimalFormat df = new DecimalFormat("#0.00");
    private double dayTotalSec = 24 * 60 * 60;

    @Override
    public List<HazAlarmStatistics> getBrokenStatistics(Page page, AlarmStatisticsRequest request) {
        List<HazAlarmStatistics> result = new ArrayList<>();

        LambdaQueryWrapper<HazAlarmBrokenEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmBrokenEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmBrokenEntity::getAlarmTime, request.getEndTime());
        List<HazAlarmBrokenEntity> alarmList = hazAlarmBrokenService.list(wrapper);

        for (HazAlarmBrokenEntity alarmEntity : alarmList) {
            Long monitorFactorId = alarmEntity.getMonitorFactorId();
            Long hazardSourceId = alarmEntity.getHazardSourceId();
            Long durationTime = alarmEntity.getDurationTime();
            HazAlarmStatistics alarmStatistics;

            Optional<HazAlarmStatistics> first = result.stream()
                    .filter(it -> it.getMonitorFactorId().equals(monitorFactorId)).findFirst();
            if (first.isEmpty()) {
                alarmStatistics = new HazAlarmStatistics();
                alarmStatistics.setMonitorFactorId(monitorFactorId);
                alarmStatistics.setHazardSourceId(hazardSourceId);
                alarmStatistics.setTime(durationTime);
                alarmStatistics.setNum(1);

                result.add(alarmStatistics);
            } else {
                alarmStatistics = first.get();
                alarmStatistics.setNum(alarmStatistics.getNum() + 1);
                alarmStatistics.setTime(alarmStatistics.getTime() + durationTime);
            }
        }
        return result;
    }

    @Override
    public List<HazAlarmStatistics> getOverproofStatistics(Page page, AlarmStatisticsRequest request) {
        List<HazAlarmStatistics> result = new ArrayList<>();

        LambdaQueryWrapper<HazAlarmOverproofEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmOverproofEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmOverproofEntity::getAlarmTime, request.getEndTime());
        List<HazAlarmOverproofEntity> alarmList = hazAlarmOverproofService.list(wrapper);

        for (HazAlarmOverproofEntity alarmEntity : alarmList) {
            Long monitorFactorId = alarmEntity.getMonitorFactorId();
            Long hazardSourceId = alarmEntity.getHazardSourceId();
            Long durationTime = alarmEntity.getDurationTime();
            HazAlarmStatistics alarmStatistics;

            Optional<HazAlarmStatistics> first = result.stream()
                    .filter(it -> it.getMonitorFactorId().equals(monitorFactorId)).findFirst();
            if (first.isEmpty()) {
                alarmStatistics = new HazAlarmStatistics();
                alarmStatistics.setMonitorFactorId(monitorFactorId);
                alarmStatistics.setHazardSourceId(hazardSourceId);
                alarmStatistics.setTime(durationTime);
                alarmStatistics.setNum(1);

                result.add(alarmStatistics);
            } else {
                alarmStatistics = first.get();
                alarmStatistics.setNum(alarmStatistics.getNum() + 1);
                alarmStatistics.setTime(alarmStatistics.getTime() + durationTime);
            }
        }
        return result;
    }

    @Override
    public JSONArray analysisOverproof(AlarmAnalysisRequest request) {
        Date beginTime = request.getBeginTime();
        Date endTime = request.getEndTime();
        List<Long> monitorFactorIds = request.getMonitorFactorIds();

        LambdaQueryWrapper<HazAlarmOverproofEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmOverproofEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmOverproofEntity::getAlarmTime, request.getEndTime());
        wrapper.in(CollectionUtils.isNotEmpty(monitorFactorIds), HazAlarmOverproofEntity::getMonitorFactorId, monitorFactorIds);
        List<HazAlarmOverproofEntity> alarmList = hazAlarmOverproofService.list(wrapper);

        JSONArray timeArray = this.buildDayTimeArray(beginTime, endTime);
        JSONObject hazardSourceMap = new JSONObject();
        String total = "total";
        for (Long monitorFactorId : monitorFactorIds) {
            HazMonitorFactorEntity monitorFactor = remoteParkBasicDictService.getHazMonitorFactorById(monitorFactorId, SecurityConstants.FROM_IN).getData();
            if (monitorFactor != null) {
                String strHazardSourceId = String.valueOf(monitorFactor.getHazardSourceId());
                JSONObject hazardSourceO = new JSONObject();
                if (hazardSourceMap.containsKey(strHazardSourceId)) {
                    hazardSourceO = hazardSourceMap.getJSONObject(strHazardSourceId);
                } else {
                    hazardSourceO.put(total, this.buildDataArray(timeArray.size()));
                    hazardSourceMap.put(strHazardSourceId, hazardSourceO);
                }
                String strMonitorFactorId = String.valueOf(monitorFactor.getId());
                hazardSourceO.put(strMonitorFactorId, this.buildDataArray(timeArray.size()));
            }
        }

        // 构造报警数据
        for (HazAlarmOverproofEntity alarm : alarmList) {
            String strHazardSourceId = String.valueOf(alarm.getHazardSourceId());
            JSONObject hazardSourceO = hazardSourceMap.getJSONObject(strHazardSourceId);
            if (hazardSourceO == null) {
                continue;
            }
            String strMonitorFactorId = String.valueOf(alarm.getMonitorFactorId());
            JSONArray dataArray = hazardSourceO.getJSONArray(strMonitorFactorId);
            JSONArray totalDataArray = hazardSourceO.getJSONArray(total);
            String strAlarmTime = DateUtils.limitDay(alarm.getAlarmTime());
            int index = timeArray.indexOf(strAlarmTime);
            if (index > -1) {
                int num = dataArray.getIntValue(index);
                num++;
                dataArray.set(index, num);

                num = totalDataArray.getIntValue(index);
                num++;
                totalDataArray.set(index, num);
            }
        }

        // map转array
        JSONArray hazardSourceArray = new JSONArray();
        for (String strHazardSourceId : hazardSourceMap.keySet()) {
            JSONObject hazardSourceO = hazardSourceMap.getJSONObject(strHazardSourceId);
            Iterator<String> iMonitorFactor = hazardSourceO.keySet().iterator();
            JSONArray monitorFactorArray = new JSONArray();
            while (iMonitorFactor.hasNext()) {
                String strMonitorFactorId = iMonitorFactor.next();
                JSONObject monitorFactorO = new JSONObject();
                if (total.equals(strMonitorFactorId)) {
                    monitorFactorO.put("factorName", "总数");
                } else {
                    HazMonitorFactorEntity monitorFactor = remoteParkBasicDictService.getHazMonitorFactorById(Long.valueOf(strMonitorFactorId), SecurityConstants.FROM_IN).getData();
                    monitorFactorO.put("factorName", monitorFactor.getFactorName());
                }

                monitorFactorO.put("data", hazardSourceO.get(strMonitorFactorId));
                monitorFactorArray.add(monitorFactorO);
            }

            HazHazardSourceEntity hazardSource = remoteParkBasicDictService.getHazHazardSourceById(Long.valueOf(strHazardSourceId), SecurityConstants.FROM_IN).getData();
            JSONObject hazardSourceDataO = new JSONObject();
            hazardSourceDataO.put("id", hazardSource.getId());
            hazardSourceDataO.put("hazardSourceName", hazardSource.getHazardName());
            hazardSourceDataO.put("monitorFactorArray", monitorFactorArray);
            hazardSourceDataO.put("timeArray", timeArray);
            hazardSourceArray.add(hazardSourceDataO);
        }

        return hazardSourceArray;
    }

    @Override
    public JSONArray analysisBroken(AlarmAnalysisRequest request) {
        // 构造时间
        Date beginTime = request.getBeginTime();
        Date endTime = request.getEndTime();
        Calendar cal = Calendar.getInstance();
        cal.setTime(endTime);
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.add(Calendar.SECOND, -1);
        endTime = cal.getTime();
        JSONArray timeArray = this.buildDayTimeArray(beginTime, endTime);

        JSONObject hazardSourceMap = new JSONObject();
        List<Long> monitorFactorIds = request.getMonitorFactorIds();
        int monitorFactorNum = 0;
        for (Long monitorFactorId : monitorFactorIds) {
            HazMonitorFactorEntity monitorFactor = remoteParkBasicDictService.getHazMonitorFactorById(monitorFactorId, SecurityConstants.FROM_IN).getData();
            if (monitorFactor != null) {
                monitorFactorNum++;
                String strHazardSourceId = String.valueOf(monitorFactor.getHazardSourceId());
                if (!hazardSourceMap.containsKey(strHazardSourceId)) {
                    hazardSourceMap.put(strHazardSourceId, this.buildDataArray(timeArray.size()));
                }
            }
        }

        LambdaQueryWrapper<HazAlarmBrokenEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmBrokenEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmBrokenEntity::getAlarmTime, request.getEndTime());
        wrapper.in(CollectionUtils.isNotEmpty(monitorFactorIds), HazAlarmBrokenEntity::getMonitorFactorId, monitorFactorIds);
        List<HazAlarmBrokenEntity> alarmList = hazAlarmBrokenService.list(wrapper);
        this.buildDayBrokenData(alarmList, hazardSourceMap, timeArray);

        // map转array
        JSONArray hazardSourceArray = new JSONArray();
        for (String strHazardSourceId : hazardSourceMap.keySet()) {
            HazHazardSourceEntity hazardSource = remoteParkBasicDictService.getHazHazardSourceById(Long.valueOf(strHazardSourceId), SecurityConstants.FROM_IN).getData();
            JSONObject hazardSourceO = new JSONObject();
            hazardSourceO.put("id", hazardSource.getId());
            hazardSourceO.put("hazardSourceName", hazardSource.getHazardName());
            JSONArray dataArray = hazardSourceMap.getJSONArray(strHazardSourceId);
            this.calculateBrokenSecPercent(dataArray, monitorFactorNum, "month");
            hazardSourceO.put("dataArray", dataArray);
            hazardSourceO.put("timeArray", timeArray);
            hazardSourceArray.add(hazardSourceO);
        }

        return hazardSourceArray;
    }

    @Override
    public JSONObject monitorMonth(AlarmAnalysisRequest request) {
        JSONObject result = new JSONObject();

        Calendar cal = Calendar.getInstance();
        cal.setTime(request.getMonth());
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date beginTime = cal.getTime();
        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.SECOND, -1);
        Date endTime = cal.getTime();

        JSONArray timeArray = this.buildDayTimeArray(beginTime, endTime);

        // 构造原始数据
        List<HazHazardSourceEntity> hazardSourceList = remoteParkBasicDictService.getHazHazardSourceList(SecurityConstants.FROM_IN).getData();
        JSONObject originData = this.buildOriginData(hazardSourceList, timeArray);
        JSONObject overproofMap = originData.getJSONObject("overproofMap");
        JSONObject brokenMap = originData.getJSONObject("brokenMap");

        // 超标报警数据
        this.buildOverproofData(beginTime, endTime, overproofMap, timeArray, "month");

        // 断网报警数据
        LambdaQueryWrapper<HazAlarmBrokenEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmBrokenEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmBrokenEntity::getAlarmTime, request.getEndTime());
        List<HazAlarmBrokenEntity> alarmList = hazAlarmBrokenService.list(wrapper);
        this.buildDayBrokenData(alarmList, brokenMap, timeArray);

        // 返回数据构造
        JSONObject tempO = this.buildHazardSourceArray(hazardSourceList, timeArray, overproofMap, brokenMap, "month", request);
        JSONArray hazardSourceArray = tempO.getJSONArray("hazardSourceArray");
        JSONArray brokenTotalDataArray = tempO.getJSONArray("brokenTotalDataArray");
        result.put("hazardSourceArray", hazardSourceArray);

        // 全部断网报警计算
        this.calculateBrokenSecPercent(brokenTotalDataArray, hazardSourceList.size(), "month");
        JSONObject brokenChart = new JSONObject();
        brokenChart.put("timeArray", timeArray);
        brokenChart.put("dataArray", brokenTotalDataArray);
        result.put("brokenChart", brokenChart);

        return result;
    }

    @Override
    public JSONObject monitorYear(AlarmAnalysisRequest request) {
        JSONObject result = new JSONObject();
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, request.getYear());
        cal.set(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date beginTime = cal.getTime();
        cal.add(Calendar.YEAR, 1);
        cal.add(Calendar.SECOND, -1);
        Date endTime = cal.getTime();

        JSONArray timeArray = this.buildMonthTimeArray(beginTime, endTime);

        // 构造原始数据
        List<HazHazardSourceEntity> hazardSourceList = remoteParkBasicDictService.getHazHazardSourceList(SecurityConstants.FROM_IN).getData();
        JSONObject originData = this.buildOriginData(hazardSourceList, timeArray);
        JSONObject overproofMap = originData.getJSONObject("overproofMap");
        JSONObject brokenMap = originData.getJSONObject("brokenMap");

        // 超标报警数据
        this.buildOverproofData(beginTime, endTime, overproofMap, timeArray, "year");

        // 断网报警数据
        LambdaQueryWrapper<HazAlarmBrokenEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), HazAlarmBrokenEntity::getAlarmTime, request.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(request.getEndTime()), HazAlarmBrokenEntity::getAlarmTime, request.getEndTime());
        List<HazAlarmBrokenEntity> alarmList = hazAlarmBrokenService.list(wrapper);
        this.buildMonthBrokenData(alarmList, brokenMap, timeArray);

        // 返回数据构造
        JSONObject tempO = this.buildHazardSourceArray(hazardSourceList, timeArray, overproofMap, brokenMap, "year", request);
        JSONArray hazardSourceArray = tempO.getJSONArray("hazardSourceArray");
        JSONArray brokenTotalDataArray = tempO.getJSONArray("brokenTotalDataArray");
        result.put("hazardSourceArray", hazardSourceArray);

        // 全部断网报警计算
        this.calculateBrokenSecPercent(brokenTotalDataArray, hazardSourceList.size(), "year");
        JSONObject brokenChart = new JSONObject();
        brokenChart.put("timeArray", timeArray);
        brokenChart.put("dataArray", brokenTotalDataArray);
        result.put("brokenChart", brokenChart);

        return result;
    }

    @Override
    public JSONArray rtDataHis(HazRtDataHisDTO hazRtDataHisDTO) {
        JSONObject monitorFactorMap = new JSONObject();
        LambdaQueryWrapper<HazRtDataHisEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(ObjectUtil.isNotNull(hazRtDataHisDTO.getBeginTime()), HazRtDataHisEntity::getDataTime, hazRtDataHisDTO.getBeginTime());
        wrapper.le(ObjectUtil.isNotNull(hazRtDataHisDTO.getEndTime()), HazRtDataHisEntity::getDataTime, hazRtDataHisDTO.getEndTime());
        wrapper.eq(ObjectUtil.isNotNull(hazRtDataHisDTO.getHazardSourceId()), HazRtDataHisEntity::getHazardSourceId, hazRtDataHisDTO.getHazardSourceId());
        wrapper.orderByAsc(HazRtDataHisEntity::getDataTime);

        List<Long> monitorFactorIds = hazRtDataHisDTO.getMonitorFactorIds();
        wrapper.in(CollectionUtils.isNotEmpty(monitorFactorIds), HazRtDataHisEntity::getMonitorFactorId, monitorFactorIds);
        List<HazRtDataHisEntity> rtDataHisList = hazRtDataHisService.list(wrapper);
        for (HazRtDataHisEntity rtDataHis : rtDataHisList) {
            String strMonitorFactorId = String.valueOf(rtDataHis.getMonitorFactorId());
            JSONObject monitorFactorO = new JSONObject();
            if (monitorFactorMap.containsKey(strMonitorFactorId)) {
                monitorFactorO = monitorFactorMap.getJSONObject(strMonitorFactorId);
            } else {
                monitorFactorO.put("timeArray", new JSONArray());
                monitorFactorO.put("dataArray", new JSONArray());
            }

            JSONArray timeArray = monitorFactorO.getJSONArray("timeArray");
            JSONArray dataArray = monitorFactorO.getJSONArray("dataArray");

            timeArray.add(rtDataHis.getDataTimeStr());
            dataArray.add(rtDataHis.getMonitorData());

            monitorFactorMap.put(strMonitorFactorId, monitorFactorO);
        }

        JSONArray result = new JSONArray();
        for (String strMonitorFactorId : monitorFactorMap.keySet()) {
            HazMonitorFactorEntity monitorFactor = remoteParkBasicDictService.getHazMonitorFactorById(Long.valueOf(strMonitorFactorId), SecurityConstants.FROM_IN).getData();
            JSONObject monitorFactorO = monitorFactorMap.getJSONObject(strMonitorFactorId);
            monitorFactorO.put("monitorFactor", monitorFactor);
            result.add(monitorFactorO);
        }

        return result;
    }

    private JSONArray buildDayTimeArray(Date beginTime, Date endTime) {
        JSONArray timeArray = new JSONArray();
        Calendar cal = Calendar.getInstance();
        cal.setTime(beginTime);
        while (cal.getTimeInMillis() < endTime.getTime()) {
            timeArray.add(DateUtils.limitDay(cal.getTime()));
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return timeArray;
    }

    private JSONArray buildDataArray(int size) {
        JSONArray dataArray = new JSONArray();
        for (int i = 0; i < size; i++) {
            dataArray.add(0);
        }
        return dataArray;
    }

    private void calculateBrokenSecPercent(JSONArray dataArray, int totalNum, String timeType) {
        for (int i = 0; i < dataArray.size(); i++) {
            double val = dataArray.getDoubleValue(i);
            if (val > 0) {
                int maxDay = 1;
                if ("year".equals(timeType)) {
                    maxDay = DateUtils.getMonthMaxDay(i);
                }
                val = val / (dayTotalSec * maxDay) / totalNum * 100;
                dataArray.set(i, df.format(val));
            }
        }
    }

    private void buildDayBrokenData(List<HazAlarmBrokenEntity> hazBrokenList, JSONObject hazardSourceMap, JSONArray timeArray) {
        Calendar cal = Calendar.getInstance();
        for (HazAlarmBrokenEntity hazBroken : hazBrokenList) {
            String strHazardSourceId = String.valueOf(hazBroken.getHazardSourceId());
            JSONArray dataArray = hazardSourceMap.getJSONArray(strHazardSourceId);
            if (dataArray == null) {
                continue;
            }

            Date alarmTime = hazBroken.getAlarmTime();
            //间隔秒？
            //int lastSec = hazBroken.getDurationTime();
            Date removeTime = hazBroken.getRemoveTime();
            if (removeTime == null) {
                removeTime = new Date();
            }
            long intervalSeconds = DateUtils.getIntervalSeconds(alarmTime, removeTime);
            int lastSec = (int) intervalSeconds;

            while (lastSec > 0) {
                Date dayEndTime = this.getDayEndTime(alarmTime);
                long dayLeftSec = (dayEndTime.getTime() - alarmTime.getTime()) / 1000;
                String strAlarmTime = DateUtils.limitDay(alarmTime);
                int index = timeArray.indexOf(strAlarmTime);
                if (index < 0) {
                    break;
                }
                int val = dataArray.getIntValue(index);
                if (lastSec <= dayLeftSec) {
                    val += lastSec;
                } else {
                    val += dayLeftSec;
                }
                dataArray.set(index, val);
                lastSec -= dayLeftSec;
                cal.setTime(alarmTime);
                cal.add(Calendar.DAY_OF_YEAR, 1);
                alarmTime = DateUtils.dateLimitDay(cal.getTime());
            }
        }
    }

    private Date getDayEndTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateUtils.dateLimitDay(date));
        cal.add(Calendar.DAY_OF_YEAR, 1);
        return cal.getTime();
    }

    private JSONObject buildOriginData(List<HazHazardSourceEntity> hazardSourceList, JSONArray timeArray) {
        JSONObject result = new JSONObject();
        JSONObject overproofMap = new JSONObject();
        JSONObject brokenMap = new JSONObject();
        for (HazHazardSourceEntity hazardSource : hazardSourceList) {
            overproofMap.put(String.valueOf(hazardSource.getId()), this.buildDataArray(timeArray.size()));
            brokenMap.put(String.valueOf(hazardSource.getId()), this.buildDataArray(timeArray.size()));
        }
        result.put("overproofMap", overproofMap);
        result.put("brokenMap", brokenMap);
        return result;
    }

    private void buildOverproofData(Date beginTime, Date endTime, JSONObject overproofMap, JSONArray timeArray, String timeType) {
        LambdaQueryWrapper<HazAlarmOverproofEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(HazAlarmOverproofEntity::getAlarmTime, beginTime);
        wrapper.le(HazAlarmOverproofEntity::getAlarmTime, endTime);
        List<HazAlarmOverproofEntity> alarmList = hazAlarmOverproofService.list(wrapper);
        for (HazAlarmOverproofEntity hazOverproof : alarmList) {
            String strHazardSourceId = String.valueOf(hazOverproof.getHazardSourceId());
            JSONArray dataArray = overproofMap.getJSONArray(strHazardSourceId);
            String strAlarmTime = "";
            if ("month".equals(timeType)) {
                strAlarmTime = DateUtils.formatDate(DateUtils.dateLimitDay(hazOverproof.getAlarmTime()), DateUtils.FORMAT_DAY);
            } else if ("year".equals(timeType)) {
                strAlarmTime = DateUtils.formatDate(DateUtils.dateLimitMonth(hazOverproof.getAlarmTime()), DateUtils.FORMAT_MINUTE);
            }
            int index = timeArray.indexOf(strAlarmTime);
            if (dataArray != null) {
                int num = dataArray.getIntValue(index);
                num++;
                dataArray.set(index, num);
            }
        }
    }

    private JSONObject buildHazardSourceArray(List<HazHazardSourceEntity> hazardSourceList, JSONArray timeArray, JSONObject overproofMap, JSONObject brokenMap, String timeType, AlarmAnalysisRequest entity) {
        JSONObject result = new JSONObject();
        JSONArray brokenTotalDataArray = this.buildDataArray(timeArray.size());
        JSONArray hazardSourceArray = new JSONArray();
        for (HazHazardSourceEntity hazardSource : hazardSourceList) {
            String strHazardSourceId = String.valueOf(hazardSource.getId());

            JSONObject hazardSourceO = new JSONObject();
            hazardSourceO.put("id", hazardSource.getId());
            hazardSourceO.put("name", hazardSource.getHazardName());
            hazardSourceO.put("timeArray", timeArray);
            // 超标报警
            JSONArray overproofDataArray = overproofMap.getJSONArray(strHazardSourceId);
            hazardSourceO.put("overproofDataArray", overproofDataArray);
            hazardSourceO.put("overproofTotal", this.getDataArrayTotal(overproofDataArray));
            // 断网报警
            JSONArray brokenDataArray = brokenMap.getJSONArray(strHazardSourceId);
            int totalBrokenSec = this.getDataArrayTotal(brokenDataArray);
            double totalBrokenPercent = 0;
            if ("month".equals(timeType)) {
                totalBrokenPercent = totalBrokenSec / (dayTotalSec * timeArray.size());
            } else if ("year".equals(timeType)) {
                int year = entity.getYear();
                int dayNum = 365;
                if (year % 4 == 0) {
                    dayNum = 365;
                }
                totalBrokenPercent = totalBrokenSec / (dayTotalSec * dayNum);
            }
            hazardSourceO.put("brokenTotal", df.format(totalBrokenPercent));
            this.calculateTwoDataArray(brokenTotalDataArray, brokenDataArray);
            // 监控因子数量
            hazardSourceO.put("monitorFactorNum", this.getMonitorFactorNum(hazardSource.getId()));

            hazardSourceArray.add(hazardSourceO);
        }
        result.put("brokenTotalDataArray", brokenTotalDataArray);
        result.put("hazardSourceArray", hazardSourceArray);
        return result;
    }

    private int getDataArrayTotal(JSONArray dataArray) {
        int result = 0;
        for (int i = 0; i < dataArray.size(); i++) {
            result += dataArray.getIntValue(i);
        }
        return result;
    }

    private void calculateTwoDataArray(JSONArray dataArray1, JSONArray dataArray2) {
        for (int i = 0; i < dataArray1.size(); i++) {
            int val1 = dataArray1.getIntValue(i);
            int val2 = dataArray2.getIntValue(i);
            dataArray1.set(i, val1 + val2);
        }
    }

    private long getMonitorFactorNum(Long hazardSourceId) {
        HazMonitorFactorEntity monitorFactor = new HazMonitorFactorEntity();
        monitorFactor.setHazardSourceId(hazardSourceId);
        return remoteParkBasicDictService.getHazMonitorFactorCount(monitorFactor, SecurityConstants.FROM_IN).getData();
    }

    private JSONArray buildMonthTimeArray(Date beginTime, Date endTime) {
        JSONArray timeArray = new JSONArray();
        Calendar cal = Calendar.getInstance();
        cal.setTime(beginTime);
        while (cal.getTimeInMillis() < endTime.getTime()) {
            timeArray.add(DateUtils.limitMinute(cal.getTime()));
            cal.add(Calendar.MONTH, 1);
        }
        return timeArray;
    }

    private void buildMonthBrokenData(List<HazAlarmBrokenEntity> hazBrokenList, JSONObject hazardSourceMap, JSONArray timeArray) {
        Calendar cal = Calendar.getInstance();
        for (HazAlarmBrokenEntity hazBroken : hazBrokenList) {
            String strHazardSourceId = String.valueOf(hazBroken.getHazardSourceId());
            JSONArray dataArray = hazardSourceMap.getJSONArray(strHazardSourceId);

            Date alarmTime = hazBroken.getAlarmTime();
            //int lastSec = hazBroken.getDurationTime();
            Date removeTime = hazBroken.getRemoveTime();
            if (removeTime == null) {
                removeTime = new Date();
            }
            long intervalSeconds = DateUtils.getIntervalSeconds(alarmTime, removeTime);
            int lastSec = (int) intervalSeconds;

            while (lastSec > 0) {
                Date monthEndTime = this.getMonthEndTime(alarmTime);
                long monthLeftSec = (monthEndTime.getTime() - alarmTime.getTime()) / 1000;
                String strAlarmTime = DateUtils.limitMouth(alarmTime);
                int index = timeArray.indexOf(strAlarmTime);
                if (index < 0) {
                    break;
                }
                int val = dataArray.getIntValue(index);
                if (lastSec <= monthLeftSec) {
                    val += lastSec;
                } else {
                    val += monthLeftSec;
                }
                dataArray.set(index, val);
                lastSec -= monthLeftSec;
                cal.setTime(alarmTime);
                cal.set(Calendar.DAY_OF_MONTH, 1);
                cal.add(Calendar.MONTH, 1);
                alarmTime = DateUtils.dateLimitDay(cal.getTime());
            }
        }
    }

    private Date getMonthEndTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateUtils.dateLimitDay(date));
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, 1);
        return cal.getTime();
    }
}
